#pragma once

#include "GraphicsPipeline.h"

class RHIRenderPass : public RHIResource
{
	struct SubpassData
	{
		std::vector<VkAttachmentReference> inputAttachments;
		std::vector<VkAttachmentReference> colorAttachments;
		VkAttachmentReference resolveAttachment;
		VkAttachmentReference depthStencilAttachment;
	};

	struct BuilderDetails {

		std::vector<RefCountPtr<RenderTarget>> renderTargets;
		std::vector<RefCountPtr<GraphicsPipeline>> pipelines;

		// External to 0 option
		VkPipelineStageFlags srcStageMask;
		VkAccessFlags srcAccessMask;

		// 0 to External option
		VkPipelineStageFlags dstStageMask;
		VkAccessFlags dstAccessMask;

		BuilderDetails();
	};

public:

	class Builder : public BuilderBase<BuilderDetails> {
		friend struct BuilderDetails;
	public:
		Builder() noexcept;
		Builder(Builder const& rhs) noexcept;
		Builder(Builder&& rhs) noexcept;
		~Builder() noexcept;
		Builder& operator=(Builder const& rhs) noexcept;
		Builder& operator=(Builder&& rhs) noexcept;

		Builder& AddRenderTarget(RefCountPtr<RenderTarget> renderTarget) noexcept;
		Builder& AddPipeline(RefCountPtr<GraphicsPipeline> pipeline) noexcept;

		Builder& SetSrcStageMask(VkPipelineStageFlags srcStageMask) noexcept;
		Builder& SetSrcAccessMask(VkAccessFlags srcAccessMask) noexcept;

		Builder& SetDstStageMask(VkPipelineStageFlags dstStageMask) noexcept;
		Builder& SetDstAccessMask(VkAccessFlags dstAccessMask) noexcept;

		RefCountPtr<RHIRenderPass> Build();
		RefCountPtr<RHIRenderPass> Build(RenderProcess* process, const std::string& name);

	private:
		friend class RHIRenderPass;
	};

	RHIRenderPass(BuilderDetails& builderDetails);

	virtual void ReleaseResource() override;

	virtual ~RHIRenderPass();

public:

	VkRenderPass GetRenderPass() const;

	const std::vector<std::vector<VkImageView>>& GetRenderTargetViewMap() const;

	const std::vector<VkClearValue>& GetClearValues() const;

	uint32 GetWidth() const;

	uint32 GetHeight() const;

	uint32 GetRenderTargetSize() const;

protected:

	uint32 GetRenderTargetIndex(RefCountPtr<RenderTarget> renderTarget) const;

protected:

	VkRenderPass mRenderPass;

	std::vector<RefCountPtr<GraphicsPipeline>> mPipelines;

	std::vector<RefCountPtr<RenderTarget>> mRenderTargets;

	// External to 0 option
	VkPipelineStageFlags mSrcStageMask;
	VkAccessFlags mSrcAccessMask;

	// 0 to External option
	VkPipelineStageFlags mDstStageMask;
	VkAccessFlags mDstAccessMask;

	std::vector<std::vector<VkImageView>> mRenderTargetViewMap;

	std::vector<VkClearValue> mClearValues;

	uint32 mWidth;

	uint32 mHeight;

	uint32 mRenderTargetSize;
};

